#include "Duinolab.h"


void DuinolabClass::Init()
{
  Wire.begin();
  _peripheral[BUTTON_PERIPHERAL].init(BUTTON_PERIPHERAL_ADDR);
  _peripheral[LED_PERIPHERAL].init(LED_PERIPHERAL_ADDR);
  _peripheral[POT_PERIPHERAL].init(POT_PERIPHERAL_ADDR);
  
  _assign_peripheral[LED_YELLOW] = 
  _assign_peripheral[LED_AMBER] = 
  _assign_peripheral[LED_ORANGE] = 
  _assign_peripheral[LED_RED] = 
  _assign_peripheral[LED_GREEN] = 
  _assign_peripheral[LED_BLUE] = LED_PERIPHERAL;
  
  _assign_port[LED_YELLOW] = 7; 
  _assign_port[LED_AMBER] = 6; 
  _assign_port[LED_ORANGE] = 5;
  _assign_port[LED_RED] = 4;
  _assign_port[LED_GREEN] = 3;
  _assign_port[LED_BLUE] = 2;

  _assign_duinopin[LED_YELLOW] = 6;  // jp  6
  _assign_duinopin[LED_AMBER] = 5; // jp 4
  _assign_duinopin[LED_ORANGE] = 3; // jp 2
  _assign_duinopin[LED_RED] = 11;  // jp 1
  _assign_duinopin[LED_GREEN] = 10;  // jp 3
  _assign_duinopin[LED_BLUE] = 9;  // jp 5

  _assign_peripheral[BUTTON_YELLOW] = 
  _assign_peripheral[BUTTON_ORANGE] = 
  _assign_peripheral[BUTTON_GREEN] = 
  _assign_peripheral[BUTTON_BLUE] = BUTTON_PERIPHERAL;

  _assign_port[BUTTON_YELLOW] = 7;
  _assign_port[BUTTON_ORANGE] = 6;
  _assign_port[BUTTON_GREEN] = 5;
  _assign_port[BUTTON_BLUE] = 4;

// jp1 = D13; jp2 = D1; jp3 = D12; jp4 = D2
  _assign_duinopin[BUTTON_YELLOW] = 2; // jp 4
  _assign_duinopin[BUTTON_ORANGE] = 1; // jp 2
  _assign_duinopin[BUTTON_GREEN] = 13; // jp 1
  _assign_duinopin[BUTTON_BLUE] = 12; // jp 3

// jp1 = A3; jp3 = A2
  _assign_peripheral[POT_BLACK] = 
  _assign_peripheral[POT_RED] = POT_PERIPHERAL;
  
  _assign_port[POT_BLACK] = 7;  // leftmost pot, labeled "pot1" on schematic
  _assign_port[POT_RED] = 6;

// jp1 = A3; jp3 = A2
  _assign_duinopin[POT_BLACK] = A3; // jp1
  _assign_duinopin[POT_RED] = A2; // jp3

}

void DuinolabClass::ConnectToArduino(uint8_t peripheral)
{
  int chip = _assign_peripheral[peripheral];
  switch(chip)  {
    case POT_PERIPHERAL:
      pinMode(_assign_duinopin[peripheral], INPUT);
      _peripheral[chip].set_mode(_assign_port[peripheral],MCP23009_OUTPUT_MODE);  // set to output vs. input
      _peripheral[chip].set_pullup(_assign_port[peripheral],MCP23009_PULLUP_ON);  // turn on pullup resistor - remember, open drain... grr...
      _peripheral[chip].set_value(_assign_port[peripheral],1);  // turn on the 4066B analog switch to enable the potentiometer      
      break;
    case BUTTON_PERIPHERAL:
      pinMode(_assign_duinopin[peripheral], INPUT);
      digitalWrite(_assign_duinopin[peripheral], HIGH);  // this is how you set pullups on the arduino...
      _peripheral[chip].set_mode(_assign_port[peripheral],MCP23009_OUTPUT_MODE);  // set to output vs. input
      _peripheral[chip].set_pullup(_assign_port[peripheral],MCP23009_PULLUP_OFF); 
      _peripheral[chip].set_value(_assign_port[peripheral],0);  // ground the other terminal of button
      break;
    case LED_PERIPHERAL:
      pinMode(_assign_duinopin[peripheral], OUTPUT);
      digitalWrite(_assign_duinopin[peripheral], LOW);  // turn off to begin with
      _peripheral[chip].set_mode(_assign_port[peripheral],MCP23009_OUTPUT_MODE);  // set to output vs. input
      _peripheral[chip].set_pullup(_assign_port[peripheral],MCP23009_PULLUP_OFF); 
      _peripheral[chip].set_value(_assign_port[peripheral],0);  // ground the other terminal of LED
      break;
    default:
      // this shouldn't happen
      break;
  }
}

void DuinolabClass::LEDOn(uint8_t led, uint8_t brightness)
{
  // should have an assert(_assign_peripheral[led] == LED_PERIPHERAL)
  analogWrite(_assign_duinopin[led], brightness);  
}

void DuinolabClass::LEDOff(uint8_t led)
{
  // should have an assert(_assign_peripheral[led] == LED_PERIPHERAL)
  digitalWrite(_assign_duinopin[led], LOW);  
}

uint16_t DuinolabClass::ReadPot(uint8_t pot)
{
  // should have an assert(_assign_peripheral[led] == POT_PERIPHERAL)
  return analogRead(_assign_duinopin[pot]);
}

uint8_t DuinolabClass::ButtonPressed(uint8_t button)
{
  // should have an assert(_assign_peripheral[led] == BUTTON_PERIPHERAL)
  return !digitalRead(_assign_duinopin[button]);
}

// preinstantiate the Duinolab object.

DuinolabClass Duinolab = DuinolabClass();
